import random
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif']=['SimHei'] # 用 来 正 常 显 示 中 文 标 签
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
# 生成模拟数据的函数
def generate_simulation_data(num_periods):
    """
    此函数用于生成模拟的保险业务数据，涵盖各类合同数量、保费收入、资产数据等，按时间段生成。
    :param num_periods: 时间段数量
    :return: 包含模拟数据的字典
    """
    data = {}
    for period in range(num_periods):
        # 合同总量
        total_contracts = random.randint(100, 1000)
        # 做首席再保人的合同数量
        chief_reinsurance_contracts = random.randint(0, total_contracts)

        # 总分保费收入
        total_premium_income = random.uniform(10000, 100000)
        # 做首席再保人的分保费收入
        chief_reinsurance_premium_income = random.uniform(0, total_premium_income)

        # 基期长/短期险原/分保费收入（这里简化为上一期数据）
        if period == 0:
            base_long_short_premium = random.uniform(1000, 10000)
        else:
            base_long_short_premium = data[period - 1]['report_long_short_premium']
        # 报告期长/短期险原/分保费收入
        report_long_short_premium = random.uniform(base_long_short_premium, base_long_short_premium * 2)

        # 总原/分保费收入
        total_original_premium = random.uniform(10000, 100000)
        # 长/短期险原/分保费收入
        long_short_original_premium = random.uniform(0, total_original_premium)

        # 原/分保费收入
        original_premium = random.uniform(10000, 100000)
        # 团/个险原/分保费收入
        group_individual_premium = random.uniform(0, original_premium)

        # 新单首年原/分保费收入
        new_first_year_premium = random.uniform(1000, 10000)
        # 新单首年期/趸缴原/分保费收入
        new_first_year_single_premium = random.uniform(0, new_first_year_premium)

        # 首年期缴原/分保费收入
        first_year_premium_payment = random.uniform(1000, 10000)
        # 10年期及以上首年期缴原/分保费收入
        ten_year_plus_premium_payment = random.uniform(0, first_year_premium_payment)

        # 报告期新单原保费收入
        report_new_single_premium = random.uniform(1000, 10000)
        # 报告期犹豫期撤单保费
        report_withdrawal_premium = random.uniform(0, report_new_single_premium)

        # 总有效业务价值
        total_effective_business_value = random.uniform(10000, 100000)
        # 新单业务价值
        new_single_business_value = random.uniform(0, total_effective_business_value)

        # 期初总资产（这里简化为上一期期末总资产）
        if period == 0:
            initial_total_assets = random.uniform(100000, 1000000)
        else:
            initial_total_assets = data[period - 1]['final_total_assets']
        # 期末总资产
        final_total_assets = random.uniform(initial_total_assets, initial_total_assets * 1.5)

        # 报告期保险业务收入
        report_insurance_income = random.uniform(10000, 100000)

        # 业务年度实际分保费收入
        actual_annual_premium = random.uniform(1000, 10000)
        # 业务年度预估分保费收入
        estimated_annual_premium = random.uniform(0, actual_annual_premium * 2)

        data[period] = {
            'total_contracts': total_contracts,
            'chief_reinsurance_contracts': chief_reinsurance_contracts,
            'total_premium_income': total_premium_income,
            'chief_reinsurance_premium_income': chief_reinsurance_premium_income,
            'base_long_short_premium': base_long_short_premium,
            'report_long_short_premium': report_long_short_premium,
            'total_original_premium': total_original_premium,
            'long_short_original_premium': long_short_original_premium,
            'original_premium': original_premium,
            'group_individual_premium': group_individual_premium,
            'new_first_year_premium': new_first_year_premium,
            'new_first_year_single_premium': new_first_year_single_premium,
            'first_year_premium_payment': first_year_premium_payment,
            'ten_year_plus_premium_payment': ten_year_plus_premium_payment,
            'report_new_single_premium': report_new_single_premium,
            'report_withdrawal_premium': report_withdrawal_premium,
            'total_effective_business_value': total_effective_business_value,
            'new_single_business_value': new_single_business_value,
            'initial_total_assets': initial_total_assets,
            'final_total_assets': final_total_assets,
            'report_insurance_income': report_insurance_income,
            'actual_annual_premium': actual_annual_premium,
            'estimated_annual_premium': estimated_annual_premium
        }
    return data

# 计算业务指标的函数
def calculate_metrics(data):
    """
    此函数根据生成的模拟数据计算各项业务指标。
    :param data: 包含模拟数据的字典
    :return: 包含计算得到的业务指标的字典
    """
    metrics = {}
    num_periods = len(data)
    for period in range(num_periods):
        period_data = data[period]
        period_metrics = {}
        # 做首席再保人或非首席再保人的合同数量占比
        period_metrics['做首席再保人或非首席再保人的合同数量占比'] = (period_data['chief_reinsurance_contracts'] / period_data['total_contracts']) * 100
        # 做首席再保人或非首席再保人的保费收入占比
        period_metrics['做首席再保人或非首席再保人的保费收入占比'] = (period_data['chief_reinsurance_premium_income'] / period_data['total_premium_income']) * 100
        # 长/短期险保费增长率
        period_metrics['长/短期险保费增长率'] = ((period_data['report_long_short_premium'] - period_data['base_long_short_premium']) / period_data['base_long_short_premium']) * 100
        # 长/短期险保费占比
        period_metrics['长/短期险保费占比'] = (period_data['long_short_original_premium'] / period_data['total_original_premium']) * 100
        # 团/个险保费占比
        period_metrics['团/个险保费占比'] = (period_data['group_individual_premium'] / period_data['original_premium']) * 100
        # 首年期/趸缴保费占比
        period_metrics['首年期/趸缴保费占比'] = (period_data['new_first_year_single_premium'] / period_data['new_first_year_premium']) * 100
        # 10年期及以上期缴保费占比
        period_metrics['10年期及以上期缴保费占比'] = (period_data['ten_year_plus_premium_payment'] / period_data['first_year_premium_payment']) * 100
        # 犹豫期保费退保率
        period_metrics['犹豫期保费退保率'] = (period_data['report_withdrawal_premium'] / (period_data['report_new_single_premium'] + period_data['report_withdrawal_premium'])) * 100
        # 新单业务价值占比
        period_metrics['新单业务价值占比'] = (period_data['new_single_business_value'] / period_data['total_effective_business_value']) * 100
        # 资产增量保费比
        period_metrics['资产增量保费比'] = ((period_data['final_total_assets'] - period_data['initial_total_assets']) / period_data['report_insurance_income']) * 100
        # 保费预估差异率
        period_metrics['保费预估差异率'] = ((period_data['estimated_annual_premium'] - period_data['actual_annual_premium']) / period_data['actual_annual_premium']) * 100

        metrics[period] = period_metrics
    return metrics

# 绘制曲线图的函数
def plot_metrics(metrics):
    """
    此函数根据计算得到的业务指标绘制曲线图。
    :param metrics: 包含业务指标的字典
    """
    num_periods = len(metrics)
    periods = np.arange(num_periods)
    metric_names = list(metrics[0].keys())

    for metric_name in metric_names:
        values = [metrics[period][metric_name] for period in periods]
        plt.figure(figsize=(10, 6))
        plt.plot(periods, values, marker='o')
        plt.xlabel('时间段')
        plt.ylabel('指标值 (%)')
        plt.title(f'{metric_name} 随时间变化曲线')
        plt.grid(True)
        plt.xticks(periods)
        plt.tight_layout()
        plt.show()

# 主函数
def main():
    """
    主函数，负责调用数据生成、指标计算和绘图函数，并打印结果。
    """
    num_periods = 12  # 假设为 12 个时间段，可根据需要调整
    # 生成模拟数据
    data = generate_simulation_data(num_periods)
    # 计算业务指标
    metrics = calculate_metrics(data)

    # 打印计算得到的业务指标
    print("业务指标:")
    for period, period_metrics in metrics.items():
        print(f"时间段 {period}:")
        for key, value in period_metrics.items():
            print(f"  {key}: {value:.2f}%")

    # 绘制曲线图
    plot_metrics(metrics)

if __name__ == "__main__":
    main()